package com.example.base;

/**
 * 功能描述
 *
 * @author Lockon.wang
 */
public class StringIntern {


    public static void main(String[] args) {
        /**
         * intern()一句话概括用来返回调用对象的引用，但是这个返回的引用是什么值就很有讲究了。
         * intern官方释义：当调用 intern方法时，如果常量池中已经包含一个等于此String对象的字符串（用equals(oject)方法确定），则返回池中的字符串。
         * 否则，将此String对象添加到池中，并返回此String对象的引用。
         */
        String s1 = new StringBuilder("ja").append("va").toString();
        System.out.println(s1.intern() == s1);
        String s2 = new StringBuilder("ja").append("va").toString();
        System.out.println(s2.intern() == s2);
        System.out.println(s2.intern() == s1);


        String str1=new String("he")+new String("llo");        //  在堆中产生三个对象，str1 只指向合并后生成的那个"hello"对象；

        String str2="hello";                             //  在常量池中找，没有“hello”，所以在常量池中生成一个此常量对象，str2指向此对象，str2是常量对象的引用。

        str1.intern();                                       //  在常量池中找，已经存在“hello”这个常量对象，故不生成常量引用.str1仍然指向堆中“hello”

        System.out.println(str1==str2); // false                    //  两个对象的地址不一样，故false





        String str11=new String("he")+new String("llo1");       //  在堆中产生三个对象，string只指向合并后生成的那个"hello"对象；

        str11.intern();                                    //  在常量池中找，没有“hello”这个常量对象，所以把字符串放到常量池并返回这个常量字符串的引用，和堆中那个对象的地址相同

        String str21="hello1";                          //  常量池中已经存在这个常量对象的引用，所以str2指向这个引用，所以str2也指向str1对象

        System.out.println(str11==str21);// true                   //  地址一样，内容一样，所以true
    }
}
